//
//  MoviePlayer.m
//  MoviePlayer
//
//  Created by 邓芮 on 15/12/4.
//  Copyright © 2015年 邓芮. All rights reserved.
//

#import "MoviePlayer.h"
#import "progress.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

@interface MoviePlayer ()<ProgressDelegate>
//播放器
@property (nonatomic, strong) AVPlayer *avplay;
@property (nonatomic, strong) AVPlayerItem *playerItem;
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
// 装载进度条和时间
@property (nonatomic, strong) UIView *bottomView;
// 开始时间
@property (nonatomic, strong) UILabel *beginLabel;
// 结束时间
@property (nonatomic, strong) UILabel *endLabel;
// 进度条
@property (nonatomic, strong) progress *playSlider;
// 播放暂停按钮
@property (nonatomic, strong) UIButton *play;
// 接收系统声音
@property (nonatomic, strong) UISlider *systemVolumeSlider;
// 声音控件
@property (nonatomic, strong) UISlider *volumeSlider;
//// 定时器
//@property (nonatomic, strong) NSTimer *timer;
// 进度条上方显示滑动方向和时间
@property (nonatomic, strong) UILabel *horizontalLabel;
// 监听播放状态
@property (nonatomic, strong) id playbackTimeObserver;

// 装载返回的view
@property (nonatomic, strong) UIView *topView;

@end

@implementation MoviePlayer
{
    CGFloat sumTime;
    BOOL isVolume;
    NSDateFormatter *_dateFormatter;
    PanDirection panDirection;
}

- (instancetype)initWithFrame:(CGRect)frame url:(NSString *)url
{
    self = [super initWithFrame:frame];
    if (self)
    {
        // 播放器
        NSURL *videoUrl = [NSURL URLWithString:url];
        self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
        // 监听播放状态
        [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//         监听是否可以播放
        [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
        
        // 因网络问题视频暂停后的通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerPlay) name:AVPlayerItemPlaybackStalledNotification object:nil];
//        AVPlayerItemPlaybackStalledNotification
//         视频结束通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
        
        self.avplay = [AVPlayer playerWithPlayerItem:self.playerItem];
        self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avplay];
        self.playerLayer.frame = self.bounds;
        self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self.layer addSublayer:self.playerLayer];
        [self.avplay play];
        
        
        // 播放按钮
        self.play = [UIButton buttonWithType:UIButtonTypeCustom];
        CGFloat playWidth = 45 * frame.size.width / 736;
//        self.play.backgroundColor = [UIColor redColor];
        self.play.frame = CGRectMake(0, 0, playWidth, playWidth);
        self.play.center = CGPointMake(frame.size.width / 2, frame.size.height / 2);
        [self.play setImage:[UIImage imageNamed:@"stop"] forState:UIControlStateNormal];
        [self.play setImage:[UIImage imageNamed:@"play"] forState:UIControlStateSelected];
        self.play.hidden = YES;
        [self.play addTarget:self action:@selector(playMovie:) forControlEvents:UIControlEventTouchUpInside];
        [self.play addTarget:self action:@selector(viewNotDismiss) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.play];
        
        
        // 装载进度条和时间
        CGFloat bottonHeight = 45 * frame.size.width / 736;
        self.bottomView = [[UIView alloc]initWithFrame:CGRectMake(0, frame.size.height - bottonHeight, frame.size.width, bottonHeight)];
//        self.bottomView.backgroundColor = [UIColor redColor];
        
        self.bottomView.hidden = YES;
        CGFloat labelWidth = 60 * frame.size.width / 736;
        self.beginLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, labelWidth, bottonHeight)];
        self.beginLabel.text = @"00:00";
        self.beginLabel.textColor = [UIColor whiteColor];
        self.beginLabel.textAlignment = NSTextAlignmentCenter;
        [self.bottomView addSubview:self.beginLabel];
        
        CGFloat progreeX = self.beginLabel.frame.size.width + 10 * KWidth / 736;
        self.playSlider = [[progress alloc]initWithFrame:CGRectMake(progreeX, 0, frame.size.width - progreeX * 2, bottonHeight)];
        self.playSlider.slider.minimumTrackTintColor = [UIColor whiteColor];
        self.playSlider.slider.maximumTrackTintColor = [UIColor grayColor];
        [self.playSlider.slider addTarget:self action:@selector(valueChange:other:) forControlEvents:UIControlEventValueChanged];
        self.playSlider.cacheColor = [UIColor whiteColor];
        // 设置代理
        self.playSlider.delegate = self;
        [self.bottomView addSubview:self.playSlider];
        
        self.endLabel = [[UILabel alloc]initWithFrame:CGRectMake(labelWidth + self.playSlider.frame.size.width + 10 * frame.size.width / 736, 0, labelWidth, bottonHeight)];
        self.endLabel.text = @"00:00";
        self.endLabel.textColor = [UIColor whiteColor];
        self.endLabel.textAlignment = NSTextAlignmentCenter;
        [self.bottomView addSubview:self.endLabel];
        
        [self addSubview:self.bottomView];
        
        self.topView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, 50 * frame.size.width / 736)];
        self.topView.backgroundColor = [UIColor blackColor];
        self.topView.alpha = 0.3;
//        self.topView.hidden = YES;
        
        _back = [DIYButton buttonWithType:UIButtonTypeCustom];
        CGFloat backWidth = 40 * frame.size.width / 736;
        self.back.iconImageView.image = [UIImage imageNamed:@"back-1"];
        self.back.frame = CGRectMake(0, 5 * frame.size.width / 736, frame.size.width, backWidth);
        self.back.textLabel.textColor = [UIColor whiteColor];
//        self.back.frame = CGRectMake(0, 5 * frame.size.width / 736, backWidth, backWidth);
//        [self.back setImage:[UIImage imageNamed:@"back-1"] forState:UIControlStateNormal];
//        [self.back addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
        [self.topView addSubview:self.back];
        
//        self.title = [[UILabel alloc]initWithFrame:CGRectMake(self.back.frame.size.width + 5 * frame.size.width / 736, 0, 500 * frame.size.width / 736, self.topView.frame.size.height)];
//        self.title.textColor = [UIColor whiteColor];
////        self.title.text = @"视频播放";
//        [self.topView addSubview:self.title];
        
        [self addSubview:self.topView];
        
        self.volumeSlider = [[UISlider alloc]initWithFrame:CGRectMake(0, 0, frame.size.height / 2.7, 30 * frame.size.height / 414)];
        self.volumeSlider.center = CGPointMake(50 * frame.size.height / 414, frame.size.height / 2);
        self.volumeSlider.transform = CGAffineTransformMakeRotation(M_PI * 1.5);
        [self.volumeSlider setThumbImage:[UIImage imageNamed:@"12-eye"] forState:UIControlStateNormal];
        self.volumeSlider.hidden = YES;
        
        CGFloat volumeWidth = 20 * frame.size.height / 414;
        CGFloat volumeOriginX = (self.volumeSlider.frame.size.width - volumeWidth) / 2;
        UIImageView *maxImageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.volumeSlider.frame.size.height, volumeOriginX, volumeWidth, volumeWidth)];
        maxImageView.image = [UIImage imageNamed:@"maxVolume"];
        [self.volumeSlider addSubview:maxImageView];
        
        
        UIImageView *minImageView = [[UIImageView alloc]initWithFrame:CGRectMake(-volumeWidth, volumeOriginX, volumeWidth, volumeWidth)];
        minImageView.image = [UIImage imageNamed:@"miniVolume"];
        [self.volumeSlider addSubview:minImageView];
        
        [self.volumeSlider addTarget:self action:@selector(volumeChange:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:self.volumeSlider];
        
        // 获取系统音量
        MPVolumeView *volumeView = [[MPVolumeView alloc]initWithFrame:CGRectMake(-100, 0, 30, 30)];
        for (UIView *view in volumeView.subviews
             )
        {
            if ([view isKindOfClass:[UISlider class]])
            {
                self.systemVolumeSlider = (UISlider *)view;
                self.volumeSlider.value = self.systemVolumeSlider.value;
            }
        }
        
        self.volumeSlider.maximumValue = self.systemVolumeSlider.maximumValue;
        self.volumeSlider.minimumValue = self.systemVolumeSlider.minimumValue;
        [self addSubview:volumeView];

        
        // 进度条上方滑动显示时间
        self.horizontalLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, frame.size.height / 1.3, frame.size.width, 30 * frame.size.height / 414)];
        self.horizontalLabel.text = @"<< 00:00 / --:--";
        self.horizontalLabel.textAlignment = NSTextAlignmentCenter;
        self.horizontalLabel.textColor = [UIColor whiteColor];
        self.horizontalLabel.hidden = YES;
        [self addSubview:self.horizontalLabel];
        
        [[NetworkState shareInstance]addYYToView:self];
    }
    return self;
}

#pragma mark -- 返回方法 --
- (void)back:(UIButton *)button
{
    [self.playerItem removeObserver:self forKeyPath:@"status" context:nil];
    [self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges" context:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemPlaybackStalledNotification object:nil];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(dismiss) object:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
    [self.avplay removeTimeObserver:self.playbackTimeObserver];
    [self.playerLayer removeFromSuperlayer];
    [self.avplay pause];
    self.avplay = nil;
}

#pragma mark -- 视频声音事件 --
- (void)volumeChange:(UISlider *)slider
{
    self.systemVolumeSlider.value = slider.value;
}

#pragma mark -- 播放按钮事件 --
- (void)valueChange:(UISlider *)slider other:(UIEvent *)other
{
    UITouch *touch = [[other allTouches] anyObject];
    [self viewNotDismiss];
    
    switch (touch.phase)
    {
        case UITouchPhaseBegan:
        {
            self.play.selected = YES;
            break;
        }
        case UITouchPhaseMoved:
        {
            break;
        }
        case UITouchPhaseEnded:
        {
            [self.avplay seekToTime:CMTimeMake(slider.value, 1) completionHandler:^(BOOL finished) {
                self.play.selected = NO;
                [self.avplay play];
            }];
            break;
        }
        default:
            break;
    }
}

- (void)playerPlay
{
    self.play.selected = NO;
    [self.avplay play];
}

#pragma mark -- 监听播放状态 --
- (void)monitoringPlayback:(AVPlayerItem *)playerItem
{
    __weak typeof(self) weakSelf = self;
    self.playbackTimeObserver = [self.avplay addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
        CGFloat currentSecond = playerItem.currentTime.value / playerItem.currentTime.timescale;
        [weakSelf.playSlider.slider setValue:currentSecond animated:YES];
        weakSelf.playSlider.slider.value = currentSecond;
        weakSelf.beginLabel.text = [weakSelf covertTime:currentSecond];
    }];
}

#pragma mark -- 监听 --
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"status"])
    {
        if ([self.playerItem status] == AVPlayerStatusReadyToPlay)
        {
            [[NetworkState shareInstance]finshYYToView:self];
            [self viewNotDismiss];
            CMTime duration = self.playerItem.duration;
            CGFloat totalSecond = duration.value / duration.timescale;
            self.endLabel.text = [self covertTime:totalSecond];
            self.playSlider.slider.maximumValue = CMTimeGetSeconds(duration);
            [self monitoringPlayback:self.playerItem];
            [self.avplay play];
            
            self.volumeSlider.value = self.systemVolumeSlider.value;
            self.volumeSlider.maximumValue = self.systemVolumeSlider.maximumValue;
            self.volumeSlider.minimumValue = self.systemVolumeSlider.minimumValue;
            [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(systemVolumeChange:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
            
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
            [self addGestureRecognizer:tap];
            
            UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panDirection:)];
            [self addGestureRecognizer:pan];
            
        }
        else if (self.playerItem.status == AVPlayerStatusFailed)
        {
           // NSLog(@"AVPlayerStatusFailed");
            [self.avplay removeTimeObserver:self.playbackTimeObserver];
        }
        
    }
    else if ([keyPath isEqualToString:@"loadedTimeRanges"])
    {
        NSTimeInterval timeInterval = [self availableDuration];
        self.playSlider.cache = timeInterval;
    }
}

#pragma mark -- 硬件改变系统声音 ---
- (void)systemVolumeChange:(NSNotification *)notification
{
    self.volumeSlider.value = self.systemVolumeSlider.value;
}

#pragma mark -- tap手势 --
- (void)tapAction:(UITapGestureRecognizer *)tap
{
    [self viewNotDismiss];
    
    self.play.hidden = !self.play.hidden;
    self.bottomView.hidden = !self.bottomView.hidden;
    self.topView.hidden = self.bottomView.hidden;
    self.volumeSlider.hidden = self.play.hidden;
}

#pragma mark -- pan手势 --
- (void)panDirection:(UIPanGestureRecognizer *)pan
{
    CGPoint velocity = [pan velocityInView:self];
    switch (pan.state)
    {
        case UIGestureRecognizerStateBegan:
        {
            CGFloat x = fabs(velocity.x);
            CGFloat y = fabs(velocity.y);
            if (x > y)
            {
                panDirection = PanDirectionHorizontalMoved;
                self.horizontalLabel.hidden = NO;
                sumTime = CMTimeGetSeconds(self.avplay.currentItem.currentTime);
            }
            else if (x < y)
            {
                panDirection = PanDirectionVerticalMoved;
                self.volumeSlider.hidden = NO;
                isVolume = YES;
            }
            break;
        }
        case UIGestureRecognizerStateChanged:
        {
            switch (panDirection)
            {
                case PanDirectionHorizontalMoved:
                {
                    [self panHorizontalMoved:velocity.x];
                    
                    break;
                }
                case PanDirectionVerticalMoved:
                {
                    [self panVerticalMoved:velocity.y];
                    break;
                }
                default:
                    break;
            }
            break;
        }
        case UIGestureRecognizerStateEnded:
        {
            switch (panDirection)
            {
                case PanDirectionHorizontalMoved:
                {
                    self.horizontalLabel.hidden = YES;
                 [self.avplay seekToTime:CMTimeMake(sumTime, 1) completionHandler:^(BOOL finished) {
                     [self.avplay play];
                 }];
                    sumTime = 0;
                    break;
                }
                case PanDirectionVerticalMoved:
                {
                    self.volumeSlider.hidden = YES;
                    isVolume = NO;
                    break;
                }
                default:
                    break;
            }
            break;
        }
        default:
            break;
    }

}

#pragma mark -- 手势水平移动 --
- (void)panHorizontalMoved:(CGFloat)value
{
    CMTime duration = self.playerItem.duration;
    CGFloat durationValue = CMTimeGetSeconds(duration);
    NSString *style = nil;
    if (value > 0)
    {
        style = @">>";
    }
    else if (value < 0)
    {
        style = @"<<";
    }
    sumTime += value / 204;
    if (sumTime < 0)
    {
        sumTime = 0;
    }
    else if (sumTime > durationValue)
    {
        sumTime = durationValue;
    }
    
    self.playSlider.slider.value = sumTime;
    self.horizontalLabel.text = [NSString stringWithFormat:@"%@ %@ / %@",style, [self covertTime:sumTime] , self.endLabel.text];
    self.beginLabel.text = [self covertTime:sumTime];
    
}
#pragma mark -- 手势垂直移动 --
- (void)panVerticalMoved:(CGFloat)value
{
    self.volumeSlider.value -= value / 10000;
    self.systemVolumeSlider.value = self.volumeSlider.value;
}


#pragma mark -- slider代理方法 --
- (void)touchView:(float)value
{
    self.play.selected = YES;
    CMTime time = CMTimeMake(value, 1);
    [self.avplay seekToTime:time completionHandler:^(BOOL finished) {
        [self.avplay play];
        self.play.selected = NO;
    }];
}

#pragma mark -- 缓冲条的时间 --
- (NSTimeInterval)availableDuration
{
    NSArray *loadedTimeRanges = [[self.avplay currentItem] loadedTimeRanges];
    // 获取缓冲区域
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    // 计算缓冲总进度
    NSTimeInterval result = startSeconds + durationSeconds;
    return result;
}

#pragma mark -- 视频总时间的格式 --
- (NSString *)covertTime:(CGFloat)second
{
    NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];
    if (second/3600 >= 1)
    {
        [[self dateFormatter] setDateFormat:@"HH:mm:ss"];
    }
    else
    {
        [[self dateFormatter]setDateFormat:@"mm:ss"];
    }
    NSString *showtimeNew = [[self dateFormatter] stringFromDate:d];
    return showtimeNew;
}

- (NSDateFormatter *)dateFormatter
{
    if (!_dateFormatter)
    {
        _dateFormatter = [[NSDateFormatter alloc]init];
    }
    return _dateFormatter;
}

- (void)playEnd
{
    [self.avplay seekToTime:CMTimeMake(0, 1) completionHandler:^(BOOL finished) {
        [self.avplay play];
    }];
}

- (void)playMovie:(UIButton *)button
{
    button.selected = !button.selected;
    if (button.selected)
    {
        [self.avplay pause];
    }
    else
    {
        [self.avplay play];
    }
}

#pragma mark -- 保证视图不消失的方法 每次调用这个方法 把之前的倒计时抹去 添加一个新的3s倒计时 --
- (void)viewNotDismiss
{
    // 先取消一个 3秒后消失的方法 保证不管点几次 只有一个方法在3秒执行
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(dismiss) object:nil];
    
    // 设置3秒后消失
    [self performSelector:@selector(dismiss) withObject:nil afterDelay:3];
}

- (void)dismiss
{
    self.play.hidden = YES;
    self.bottomView.hidden = YES;
    self.topView.hidden = YES;
    self.volumeSlider.hidden = YES;
    
}

- (void)dealloc
{
    [self.playerItem removeObserver:self forKeyPath:@"status" context:nil];
    [self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges" context:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemPlaybackStalledNotification object:nil];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(dismiss) object:nil];
    [self.avplay removeTimeObserver:self.playbackTimeObserver];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}


@end






















